1 package org.devaki.nextobjects.workspace.models.graphics;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import java.io.Serializable;
22 import java.awt.Cursor;
23 import java.awt.Dimension;
24 import java.awt.Graphics2D;
25 import java.awt.Color;
26 import java.awt.Point;
27 import java.awt.Polygon;
28 import java.awt.event.MouseEvent;
29 import java.awt.event.MouseMotionAdapter;
30 import java.util.Vector;
31 import javax.swing.event.MouseInputAdapter;
32 import org.devaki.nextobjects.constants.CstGraphics;
33 import org.devaki.nextobjects.ui.menus.MenuFactory;
34 import org.devaki.nextobjects.ui.toolbars.NOToolBar2;
35 import org.devaki.nextobjects.ui.workspace.models.EditorFactory;
36 import org.devaki.nextobjects.util.ModelMan;
37 import org.devaki.nextobjects.workspace.models.PhysicalModel;
38 import org.devaki.nextobjects.workspace.models.BaseModel;
39 import org.devaki.nextobjects.workspace.models.columns.Column;
40 import org.devaki.nextobjects.workspace.models.objects.BaseClass;
41 import org.devaki.nextobjects.workspace.models.objects.BaseObject;
42 import org.devaki.nextobjects.workspace.models.objects.Constraint;
43 import org.devaki.nextobjects.workspace.models.objects.Table;
44 import org.devaki.nextobjects.workspace.models.objects.InheritanceLink;
45 import org.devaki.nextobjects.workspace.models.columns.ColumnType;
46 /***
47 * This class is responsible for drawing Physical Data Models
48 *
49 * @see http://www.devaki.org/pdm.html
50 * @author <a href="mailto:eflorent@devaki.org">Emmanuel Florent</a>
51 *
52 */
53 public class PhysicalView extends BaseModelView implements Serializable
54 {
55 /***
56 * Construct a new PhysicalView object
57 * @param theDatabase the context database
58 */
59 public PhysicalView(final PhysicalModel theDatabase)
60 {
61
62 super(theDatabase);
63 this.setVisible(true);
64
65 this.drawingArea.addMouseListener(new MyMouseListener());
66 this.drawingArea.addMouseMotionListener(
67 new MyMouseMotionListener());
68 }
69 /***
70 * Create a constraint from two table.
71 * This is called by manageDND
72 * The constraint is local to the arrival table,
73 * like if the fields where moved...
74 * @param pStartTable the start table
75 * @param pEndTable the end table
76 * @return the constraint
77 */
78 private Constraint createConstraint(
79 final Table pStartTable,
80 final Table pEndTable)
81 {
82
83 Vector vfk = new Vector();
84 if (pStartTable.getPrimaryKeys().size() < 1)
85 {
86 Column newColumn = getNewStandardPk(pStartTable);
87 pStartTable.getData().addElement(newColumn);
88 vfk.addElement(newColumn);
89 }
90 else
91 {
92
93
94 vfk.addElement(pStartTable.getPrimaryKeys().firstElement());
95 }
96
97 Vector vlk = new Vector();
98
99 if (pEndTable.getPrimaryKeys().size() < 1)
100 {
101 Column newColumn2 = getNewStandardPk(pEndTable);
102 pEndTable.getData().addElement(newColumn2);
103
104 }
105
106 Column newColumn = getNewStandardFk(pStartTable, pEndTable);
107 pEndTable.getData().addElement(newColumn);
108 vlk.addElement(newColumn);
109
110 Constraint constraint =
111 new Constraint(
112 (PhysicalModel) this.myModel,
113 pEndTable,
114 vfk,
115 pStartTable,
116 vlk);
117 return constraint;
118 }
119 /***
120 * Get a new , standard primary key for a table
121 *
122 * @param pBaseClass the table
123 * @return the column
124 */
125 private static Column getNewStandardPk(final BaseClass pBaseClass)
126 {
127 Column column =
128 new Column(
129 pBaseClass.getCode() + " id",
130 pBaseClass.getCode() + "_id",
131 new ColumnType("INTEGER", "", ""),
132 "",
133 "",
134 true,
135 true,
136 true,
137 true,
138 true,
139 "",
140 "",
141 "",
142 "",
143 "",
144 "",
145 pBaseClass);
146 column.setParent(pBaseClass);
147 return column;
148 }
149 /***
150 * get a new , standard foreign key
151 * take the PK of the foreign table and
152 * add it as a F into the table.
153 *
154 * @param pParentTable the parent table
155 * @param pChildTable the child table
156 * @return the column
157 */
158 public static Column getNewStandardFk(
159 final Table pParentTable,
160 final Table pChildTable)
161 {
162 Column column;
163 Vector pk = pParentTable.getPrimaryKeys();
164
165 if (pk.size() == 0)
166 {
167
168 column = getNewStandardPk(pParentTable);
169 }
170 else
171 {
172 column =
173 new Column(
174 ((Column) pk.elementAt(0)).getName(),
175 ((Column) pk.elementAt(0)).getCode(),
176 ((Column) pk.elementAt(0)).getType(),
177 "",
178 "",
179 false,
180 true,
181 false,
182 false,
183 false,
184 "",
185 "",
186 "",
187 "",
188 "",
189 "",
190 pChildTable);
191 }
192 column.setParent(pParentTable);
193 return column;
194 }
195 /***
196 * manage d'n'd
197 */
198 public final void manageDnD()
199 {
200
201 if (ModelMan.getDraggedObject() instanceof Table)
202 {
203
204 if (ModelMan.getDropTargetObject() instanceof Table)
205 {
206 if (NOToolBar2.getCurrentTool()
207 == NOToolBar2.TOOL_CONSTRAINT)
208 {
209 ModelMan.addConstraint(
210 (PhysicalModel) ModelMan.getCurrentModel(),
211 createConstraint(
212 (Table) ModelMan.getDraggedObject(),
213 (Table) ModelMan.getDropTargetObject()));
214 }
215 else if (
216 NOToolBar2.getCurrentTool()
217 == NOToolBar2.TOOL_INHERITANCE)
218 {
219 if (!ModelMan
220 .getDraggedObject()
221 .equals(ModelMan.getDropTargetObject()))
222 {
223 InheritanceLink newInheritanceLink =
224 new InheritanceLink(
225 this.myModel,
226 (BaseClass) ModelMan.getDraggedObject(),
227 (BaseClass) ModelMan.getDropTargetObject());
228 ModelMan.addInheritanceLink(
229 (BaseModel) myModel,
230 newInheritanceLink);
231 }
232 }
233
234 ModelMan.setDraggedObject(null);
235 ModelMan.setDropTargetObject(null);
236 drawingArea.repaint();
237 }
238 }
239 }
240 /***
241 * The mouse listener who listen clicks (but not moves)
242 */
243 class MyMouseListener extends MouseInputAdapter
244 {
245 /***
246 * What to do when mouse is pressed.
247 * @param e the mouse event
248 */
249 public final void mousePressed(final MouseEvent e)
250 {
251 this.evaluatePopup(e);
252
253 x1 = e.getX();
254 y1 = e.getY();
255 if ((NOToolBar2.getCurrentTool() != NOToolBar2.TOOL_RESIZE)
256 && (NOToolBar2.getCurrentTool() != NOToolBar2.TOOL_TABLE)
257 && (NOToolBar2.getCurrentTool()
258 != NOToolBar2.TOOL_ASSOCIATION))
259 {
260 ObjectView[] tmp = getVisibleObjectView();
261
262 int j = 0;
263 boolean gotIt = false;
264 while (j < tmp.length)
265 {
266 if (((Polygon) tmp[j].getSurface()).contains(x1, y1))
267 {
268
269 gotIt = true;
270 dx = x1 - tmp[j].getLocation().x;
271 dy = y1 - tmp[j].getLocation().y;
272 if (e.isControlDown())
273 {
274 ModelMan.addCurrentObject(tmp[j].myObject);
275 }
276 else
277 {
278 ModelMan.setCurrentObject(tmp[j].myObject);
279 }
280 j = tmp.length;
281 }
282 ++j;
283 }
284 if (!gotIt)
285 {
286 ModelMan.resetCurrentObjects();
287 }
288 if (e.getClickCount() == 2)
289 {
290 NOToolBar2.setCurrentTool(-1);
291 EditorFactory.getObjectEdit(
292 ModelMan.getCurrentObject());
293 }
294 }
295
296 switch (NOToolBar2.getCurrentTool())
297 {
298 case NOToolBar2.TOOL_INHERITANCE :
299 case NOToolBar2.TOOL_CONSTRAINT :
300 {
301 ModelMan.setDraggedObject(
302 ModelMan.getCurrentObject());
303 break;
304 }
305 case NOToolBar2.TOOL_TABLE :
306 {
307 ModelMan.addTable(
308 (PhysicalModel) myModel,
309 e.getPoint());
310
311 ModelMan.moveCurrentObjects(0, 0);
312 break;
313 }
314 case NOToolBar2.TOOL_LABEL :
315 {
316 ModelMan.addLabel(myModel, e.getPoint());
317
318 ModelMan.moveCurrentObjects(0, 0);
319 break;
320 }
321 default :
322
323 }
324 if (ModelMan.getCurrentObject() == null
325 && e.getClickCount() == 2)
326 {
327 NOToolBar2.setCurrentTool(-1);
328 EditorFactory.getModelEdit();
329 }
330
331 drawingArea.repaint();
332 }
333 /***
334 * What to do when mouse is released.
335 * @param e the mouse event
336 */
337 public final void mouseReleased(final MouseEvent e)
338 {
339 this.evaluatePopup(e);
340 fullRefresh = true;
341 ModelMan.resetActionLocations();
342 calculateRectangle();
343 x2 = e.getX();
344 y2 = e.getY();
345 if (NOToolBar2.getCurrentTool() == NOToolBar2.TOOL_SELECTION
346 && ModelMan.getCurrentObject() != null)
347 {
348 ModelMan.moveCurrentObjects(x2 - x1, y2 - y1);
349 }
350 else if (
351 (NOToolBar2.getCurrentTool() == NOToolBar2.TOOL_CONSTRAINT
352 || NOToolBar2.getCurrentTool()
353 == NOToolBar2.TOOL_INHERITANCE)
354 && ModelMan.getDraggedObject() != null
355 && ModelMan.getDropTargetObject() != null)
356 {
357 manageDnD();
358 }
359 NOToolBar2.setCurrentTool(NOToolBar2.TOOL_SELECTION);
360 drawingArea.repaint();
361 }
362 /***
363 * Evaluate if popup menu has been requested
364 * @param e mouse event
365 */
366 private void evaluatePopup(final MouseEvent e)
367 {
368 if (e.isPopupTrigger()
369 && (NOToolBar2.getCurrentTool() != NOToolBar2.TOOL_TABLE))
370 {
371 MenuFactory.getModelPopupMenu().setData(
372 e.getX(),
373 e.getY());
374 MenuFactory.getModelPopupMenu().show(
375 drawingArea,
376 e.getX(),
377 e.getY());
378 }
379 }
380 }
381 /***
382 * The mouse listener who listen moves (but not cliks)
383 */
384 class MyMouseMotionListener extends MouseMotionAdapter
385 {
386 /***
387 * What to do when mouse is dragged
388 * @param e the mouse event
389 */
390 public final void mouseDragged(final MouseEvent e)
391 {
392 Graphics2D ptrGphx2D = (Graphics2D) drawingArea.getGraphics();
393 x2 = e.getX();
394 y2 = e.getY();
395
396 switch (NOToolBar2.getCurrentTool())
397 {
398
399 case NOToolBar2.TOOL_SELECTION :
400 if (ModelMan.getCurrentObjects().size() > 0)
401 {
402 if (ModelMan.getCurrentObject().getObjectView()
403 instanceof LineView)
404 {
405
406 x1 = 0;
407 y1 = 0;
408 dx = 0;
409 dy = 0;
410 }
411 ModelMan
412 .getCurrentObject()
413 .getObjectView()
414 .setActionLocation(
415 x2 - dx,
416 y2 - dy);
417 }
418 break;
419
420 case NOToolBar2.TOOL_RESIZE :
421 if (ModelMan.getCurrentObject() != null)
422 {
423
424 int curX =
425 (int) ModelMan
426 .getCurrentObject()
427 .getObjectView()
428 .getLocation()
429 .getX();
430 int curY =
431 (int) ModelMan
432 .getCurrentObject()
433 .getObjectView()
434 .getLocation()
435 .getY();
436 int curWidth =
437 (int) ModelMan
438 .getCurrentObject()
439 .getObjectView()
440 .getSize()
441 .getWidth();
442 int curHeight =
443 (int) ModelMan
444 .getCurrentObject()
445 .getObjectView()
446 .getSize()
447 .getHeight();
448
449 switch (getCursor().getType())
450 {
451 case SelectionPoint.NORTH_WEST :
452 if ((curWidth + curX - x2
453 >= CstGraphics.MIN_OBJECT_SIZE.getWidth())
454 && (curHeight + curY - y2
455 >= CstGraphics
456 .MIN_OBJECT_SIZE
457 .getHeight()))
458 {
459 ModelMan
460 .getCurrentObject()
461 .getObjectView()
462 .setLocation(
463 new Point(x2, y2));
464 ModelMan
465 .getCurrentObject()
466 .getObjectView()
467 .setSize(
468 new Dimension(
469 curWidth + curX - x2,
470 curHeight + curY - y2));
471 }
472 break;
473 case SelectionPoint.NORTH :
474 if (curHeight + curY - y2
475 >= CstGraphics
476 .MIN_OBJECT_SIZE
477 .getHeight())
478 {
479 ModelMan
480 .getCurrentObject()
481 .getObjectView()
482 .setLocation(
483 new Point(curX, y2));
484 ModelMan
485 .getCurrentObject()
486 .getObjectView()
487 .setSize(
488 new Dimension(
489 curWidth,
490 curHeight + curY - y2));
491 }
492 break;
493 case SelectionPoint.NORTH_EAST :
494 if ((x2 - curX
495 >= CstGraphics.MIN_OBJECT_SIZE.getWidth())
496 && (curHeight + curY - y2
497 >= CstGraphics
498 .MIN_OBJECT_SIZE
499 .getHeight()))
500 {
501 ModelMan
502 .getCurrentObject()
503 .getObjectView()
504 .setLocation(
505 new Point(curX, y2));
506 ModelMan
507 .getCurrentObject()
508 .getObjectView()
509 .setSize(
510 new Dimension(
511 x2 - curX,
512 curHeight + curY - y2));
513 }
514 break;
515 case SelectionPoint.WEST :
516 if (curWidth + curX - x2
517 >= CstGraphics.MIN_OBJECT_SIZE.getWidth())
518 {
519 ModelMan
520 .getCurrentObject()
521 .getObjectView()
522 .setLocation(
523 new Point(x2, curY));
524 ModelMan
525 .getCurrentObject()
526 .getObjectView()
527 .setSize(
528 new Dimension(
529 curWidth + curX - x2,
530 curHeight));
531 }
532 break;
533 case SelectionPoint.EAST :
534 if (x2 - curX
535 >= CstGraphics.MIN_OBJECT_SIZE.getWidth())
536 {
537 ModelMan
538 .getCurrentObject()
539 .getObjectView()
540 .setSize(
541 new Dimension(
542 x2 - curX,
543 curHeight));
544 }
545 break;
546 case SelectionPoint.SOUTH_WEST :
547 if ((curWidth + curX - x2
548 >= CstGraphics.MIN_OBJECT_SIZE.getWidth())
549 && (y2 - curY
550 >= CstGraphics
551 .MIN_OBJECT_SIZE
552 .getHeight()))
553 {
554 ModelMan
555 .getCurrentObject()
556 .getObjectView()
557 .setLocation(
558 new Point(x2, curY));
559 ModelMan
560 .getCurrentObject()
561 .getObjectView()
562 .setSize(
563 new Dimension(
564 curWidth + curX - x2,
565 y2 - curY));
566 }
567 break;
568 case SelectionPoint.SOUTH :
569 if (y2 - curY
570 >= CstGraphics
571 .MIN_OBJECT_SIZE
572 .getHeight())
573 {
574 ModelMan
575 .getCurrentObject()
576 .getObjectView()
577 .setSize(
578 new Dimension(curWidth, y2 - curY));
579 }
580 break;
581 case SelectionPoint.SOUTH_EAST :
582 if ((y2 - curY
583 >= CstGraphics.MIN_OBJECT_SIZE.getHeight()
584 && x2 - curX
585 >= CstGraphics
586 .MIN_OBJECT_SIZE
587 .getWidth()))
588 {
589 ModelMan
590 .getCurrentObject()
591 .getObjectView()
592 .setSize(
593 new Dimension(
594 x2 - curX,
595 y2 - curY));
596 }
597 break;
598 default :
599
600 }
601 }
602 break;
603
604 case NOToolBar2.TOOL_INHERITANCE :
605 case NOToolBar2.TOOL_CONSTRAINT :
606
607 if (ModelMan.getDraggedObject() != null)
608 {
609
610 ptrGphx2D.setColor(
611 CstGraphics.MODEL_BACKGROUND_COLOR);
612 ptrGphx2D.fillRect(
613 Math.min(x1, x2),
614 Math.min(y1, y2),
615 Math.abs(x2 - x1),
616 Math.abs(y2 - y1));
617 ptrGphx2D.setColor(Color.BLACK);
618 ptrGphx2D.drawLine(x1, y1, x2, y2);
619
620 for (int i = 0;
621 i < ((PhysicalModel) myModel).countTable();
622 i++)
623 {
624 if (((Polygon) ((PhysicalModel) myModel)
625 .getTableAt(i)
626 .getObjectView()
627 .getSurface())
628 .contains(
629 x2
630 + e.getComponent().getX()
631 + getViewPosition().x,
632 y2
633 + e.getComponent().getY()
634 + getViewPosition().y))
635 {
636 ModelMan.setDropTargetObject(
637 (BaseObject)
638 (
639 (
640 PhysicalModel) myModel)
641 .getTableAt(
642 i));
643 break;
644 }
645 }
646 }
647 break;
648 default :
649
650 }
651
652 drawingArea.repaint();
653 }
654 /***
655 * What to do when mouse is moved.
656 * @param e the mouse event
657 */
658 public final void mouseMoved(final MouseEvent e)
659 {
660 if ((NOToolBar2.getCurrentTool() != NOToolBar2.TOOL_TABLE)
661 && (NOToolBar2.getCurrentTool()
662 != NOToolBar2.TOOL_ASSOCIATION)
663 && (NOToolBar2.getCurrentTool()
664 != NOToolBar2.TOOL_ASSOCIATION_LINK))
665 {
666 SelectionPoint[] tmp;
667 int position = 4;
668 boolean resizing = false;
669 if (ModelMan.getCurrentObject() != null)
670 {
671 tmp =
672 ((ObjectView) ModelMan
673 .getCurrentObject()
674 .getObjectView())
675 .getSelectionPoints();
676
677 for (int j = 0; j < tmp.length; j++)
678 {
679
680 if (tmp[j]
681 .getSurface()
682 .contains(e.getX(), e.getY()))
683 {
684 resizing = true;
685 position = j + 4;
686 break;
687 }
688 }
689 }
690
691 if (resizing)
692 {
693 setCursor(new Cursor(position));
694 NOToolBar2.setCurrentTool(NOToolBar2.TOOL_RESIZE);
695 }
696 else
697 {
698 setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
699 if (NOToolBar2.getCurrentTool()
700 == NOToolBar2.TOOL_RESIZE)
701 {
702 NOToolBar2.setCurrentTool(
703 NOToolBar2.TOOL_SELECTION);
704 }
705 }
706 }
707 }
708 }
709 /***
710 * set if refresh rectangle / drawing
711 * @param b refresh
712 */
713 public final void setFullRefresh(final boolean b)
714 {
715 fullRefresh = b;
716 }
717 /***
718 * return the view size
719 * @return the location
720 */
721 public final Dimension getViewSize()
722 {
723 return jScrollPane.getViewport().getViewSize();
724 }
725 /***
726 * Calculate the visibles objects
727 * @return the objects views
728 */
729 public final ObjectView[] getVisibleObjectView()
730 {
731 ObjectView[] b =
732 new ObjectView[((PhysicalModel) myModel)
733 .getInheritanceLinks()
734 .size()
735 + ((PhysicalModel) myModel).getTables().size()
736 + ((PhysicalModel) myModel).getConstraints().size()
737 + ((PhysicalModel) myModel).getLabels().size()];
738 int offset = 0;
739 for (int i = 0;
740 i < ((PhysicalModel) myModel).getInheritanceLinks().size();
741 i++)
742 {
743 b[offset] =
744 ((PhysicalModel) myModel)
745 .getInheritanceLinkAt(i)
746 .getObjectView();
747 offset++;
748 }
749 for (int i = 0;
750 i < ((PhysicalModel) myModel).getConstraints().size();
751 i++)
752 {
753 b[offset] =
754 ((PhysicalModel) myModel)
755 .getConstraintAt(i)
756 .getObjectView();
757 offset++;
758 }
759 for (int i = 0;
760 i < ((PhysicalModel) myModel).getTables().size();
761 i++)
762 {
763 b[offset] =
764 ((PhysicalModel) myModel).getTableAt(i).getObjectView();
765 offset++;
766 }
767 for (int i = 0;
768 i < ((PhysicalModel) myModel).getLabels().size();
769 i++)
770 {
771 b[offset] =
772 (ObjectView) ((PhysicalModel) myModel)
773 .getLabels()
774 .elementAt(
775 i);
776 offset++;
777 }
778 return b;
779 }
780 }